package hu.bme.mit.androtext.nav.serializer;

import com.google.inject.Inject;
import com.google.inject.Provider;
import hu.bme.mit.androtext.nav.androNav.Activity;
import hu.bme.mit.androtext.nav.androNav.AndroNavPackage;
import hu.bme.mit.androtext.nav.androNav.AndroNavRoot;
import hu.bme.mit.androtext.nav.androNav.BooleanLiteral;
import hu.bme.mit.androtext.nav.androNav.Event;
import hu.bme.mit.androtext.nav.androNav.EventLibrary;
import hu.bme.mit.androtext.nav.androNav.ImageLibrary;
import hu.bme.mit.androtext.nav.androNav.Navigation;
import hu.bme.mit.androtext.nav.androNav.PlainString;
import hu.bme.mit.androtext.nav.androNav.PreferenceActivity;
import hu.bme.mit.androtext.nav.androNav.SimpleImage;
import hu.bme.mit.androtext.nav.androNav.StringLiteral;
import hu.bme.mit.androtext.nav.androNav.Tab;
import hu.bme.mit.androtext.nav.androNav.TabActivity;
import hu.bme.mit.androtext.nav.androNav.TabImage;
import hu.bme.mit.androtext.nav.services.AndroNavGrammarAccess;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticNodeProvider.INodesForEObjectProvider;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;

@SuppressWarnings("restriction")
public class AbstractAndroNavSemanticSequencer extends AbstractSemanticSequencer {

	@Inject
	protected AndroNavGrammarAccess grammarAccess;
	
	@Inject
	protected ISemanticSequencerDiagnosticProvider diagnosticProvider;
	
	@Inject
	protected ITransientValueService transientValues;
	
	@Inject
	@GenericSequencer
	protected Provider<ISemanticSequencer> genericSequencerProvider;
	
	protected ISemanticSequencer genericSequencer;
	
	
	@Override
	public void init(ISemanticSequencer sequencer, ISemanticSequenceAcceptor sequenceAcceptor, Acceptor errorAcceptor) {
		super.init(sequencer, sequenceAcceptor, errorAcceptor);
		this.genericSequencer = genericSequencerProvider.get();
		this.genericSequencer.init(sequencer, sequenceAcceptor, errorAcceptor);
	}
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == AndroNavPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case AndroNavPackage.ACTIVITY:
				if(context == grammarAccess.getAbstractActivityRule() ||
				   context == grammarAccess.getActivityRule()) {
					sequence_Activity(context, (Activity) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.ANDRO_NAV_ROOT:
				if(context == grammarAccess.getAndroNavRootRule()) {
					sequence_AndroNavRoot(context, (AndroNavRoot) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.BOOLEAN_LITERAL:
				if(context == grammarAccess.getBooleanLiteralRule()) {
					sequence_BooleanLiteral(context, (BooleanLiteral) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.EVENT:
				if(context == grammarAccess.getEventRule()) {
					sequence_Event(context, (Event) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.EVENT_LIBRARY:
				if(context == grammarAccess.getEventLibraryRule()) {
					sequence_EventLibrary(context, (EventLibrary) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.IMAGE_LIBRARY:
				if(context == grammarAccess.getImageLibraryRule()) {
					sequence_ImageLibrary(context, (ImageLibrary) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.NAVIGATION:
				if(context == grammarAccess.getNavigationRule()) {
					sequence_Navigation(context, (Navigation) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.PLAIN_STRING:
				if(context == grammarAccess.getPlainStringRule()) {
					sequence_PlainString(context, (PlainString) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.PREFERENCE_ACTIVITY:
				if(context == grammarAccess.getAbstractActivityRule() ||
				   context == grammarAccess.getActivityRule() ||
				   context == grammarAccess.getPreferenceActivityRule()) {
					sequence_PreferenceActivity(context, (PreferenceActivity) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.SIMPLE_IMAGE:
				if(context == grammarAccess.getImageRule() ||
				   context == grammarAccess.getSimpleImageRule()) {
					sequence_SimpleImage(context, (SimpleImage) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.STRING_LITERAL:
				if(context == grammarAccess.getStringLiteralRule()) {
					sequence_StringLiteral(context, (StringLiteral) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.TAB:
				if(context == grammarAccess.getTabRule()) {
					sequence_Tab(context, (Tab) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.TAB_ACTIVITY:
				if(context == grammarAccess.getAbstractActivityRule() ||
				   context == grammarAccess.getTabActivityRule()) {
					sequence_TabActivity(context, (TabActivity) semanticObject); 
					return; 
				}
				else break;
			case AndroNavPackage.TAB_IMAGE:
				if(context == grammarAccess.getImageRule() ||
				   context == grammarAccess.getTabImageRule()) {
					sequence_TabImage(context, (TabImage) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     (name=ID uimodel=[AndroGuiRoot|ID])
	 *
	 * Features:
	 *    name[1, 1]
	 *    uimodel[1, 1]
	 */
	protected void sequence_Activity(EObject context, Activity semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.ABSTRACT_ACTIVITY__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.ABSTRACT_ACTIVITY__NAME));
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.ACTIVITY__UIMODEL) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.ACTIVITY__UIMODEL));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getActivityAccess().getNameIDTerminalRuleCall_0_1_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getActivityAccess().getUimodelAndroGuiRootIDTerminalRuleCall_0_4_0_1(), semanticObject.getUimodel());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID navigation=Navigation imageLibrary=ImageLibrary? eventLibrary=EventLibrary?)
	 *
	 * Features:
	 *    name[1, 1]
	 *    navigation[1, 1]
	 *    imageLibrary[0, 1]
	 *    eventLibrary[0, 1]
	 */
	protected void sequence_AndroNavRoot(EObject context, AndroNavRoot semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (isTrue?='true'?)
	 *
	 * Features:
	 *    isTrue[0, 1]
	 */
	protected void sequence_BooleanLiteral(EObject context, BooleanLiteral semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (events+=Event*)
	 *
	 * Features:
	 *    events[0, *]
	 */
	protected void sequence_EventLibrary(EObject context, EventLibrary semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     name=ID
	 *
	 * Features:
	 *    name[1, 1]
	 */
	protected void sequence_Event(EObject context, Event semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.EVENT__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.EVENT__NAME));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getEventAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (images+=Image*)
	 *
	 * Features:
	 *    images[0, *]
	 */
	protected void sequence_ImageLibrary(EObject context, ImageLibrary semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (mainActivity=AbstractActivity activities+=AbstractActivity*)
	 *
	 * Features:
	 *    mainActivity[1, 1]
	 *    activities[0, *]
	 */
	protected void sequence_Navigation(EObject context, Navigation semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     value=STRING
	 *
	 * Features:
	 *    value[1, 1]
	 */
	protected void sequence_PlainString(EObject context, PlainString semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.PLAIN_STRING__VALUE) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.PLAIN_STRING__VALUE));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getPlainStringAccess().getValueSTRINGTerminalRuleCall_0(), semanticObject.getValue());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID uimodel=[AndroGuiRoot|ID])
	 *
	 * Features:
	 *    name[1, 1]
	 *    uimodel[1, 1]
	 */
	protected void sequence_PreferenceActivity(EObject context, PreferenceActivity semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.ABSTRACT_ACTIVITY__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.ABSTRACT_ACTIVITY__NAME));
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.ACTIVITY__UIMODEL) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.ACTIVITY__UIMODEL));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getPreferenceActivityAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getPreferenceActivityAccess().getUimodelAndroGuiRootIDTerminalRuleCall_4_0_1(), semanticObject.getUimodel());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID importedURI=STRING)
	 *
	 * Features:
	 *    name[1, 1]
	 *    importedURI[1, 1]
	 */
	protected void sequence_SimpleImage(EObject context, SimpleImage semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.IMAGE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.IMAGE__NAME));
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.SIMPLE_IMAGE__IMPORTED_URI) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.SIMPLE_IMAGE__IMPORTED_URI));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getSimpleImageAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getSimpleImageAccess().getImportedURISTRINGTerminalRuleCall_3_0(), semanticObject.getImportedURI());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     ((begin=''' parts+=PlainString? parts+=PlainString* end=''') | (begin='"' parts+=PlainString? parts+=PlainString* end='"'))
	 *
	 * Features:
	 *    begin[0, 2]
	 *    parts[0, *]
	 *    end[0, 2]
	 */
	protected void sequence_StringLiteral(EObject context, StringLiteral semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID position?='top'? tabs+=Tab+)
	 *
	 * Features:
	 *    name[1, 1]
	 *    position[0, 1]
	 *    tabs[1, *]
	 */
	protected void sequence_TabActivity(EObject context, TabActivity semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID selected=[SimpleImage|ID] unselected=[SimpleImage|ID])
	 *
	 * Features:
	 *    name[1, 1]
	 *    selected[1, 1]
	 *    unselected[1, 1]
	 */
	protected void sequence_TabImage(EObject context, TabImage semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.IMAGE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.IMAGE__NAME));
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.TAB_IMAGE__SELECTED) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.TAB_IMAGE__SELECTED));
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.TAB_IMAGE__UNSELECTED) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.TAB_IMAGE__UNSELECTED));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getTabImageAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName());
		feeder.accept(grammarAccess.getTabImageAccess().getSelectedSimpleImageIDTerminalRuleCall_3_0_1(), semanticObject.getSelected());
		feeder.accept(grammarAccess.getTabImageAccess().getUnselectedSimpleImageIDTerminalRuleCall_5_0_1(), semanticObject.getUnselected());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (tag=STRING activity=[Activity|ID] image=[TabImage|ID])
	 *
	 * Features:
	 *    tag[1, 1]
	 *    activity[1, 1]
	 *    image[1, 1]
	 */
	protected void sequence_Tab(EObject context, Tab semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.TAB__TAG) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.TAB__TAG));
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.TAB__ACTIVITY) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.TAB__ACTIVITY));
			if(transientValues.isValueTransient(semanticObject, AndroNavPackage.Literals.TAB__IMAGE) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, AndroNavPackage.Literals.TAB__IMAGE));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getTabAccess().getTagSTRINGTerminalRuleCall_1_0(), semanticObject.getTag());
		feeder.accept(grammarAccess.getTabAccess().getActivityActivityIDTerminalRuleCall_4_0_1(), semanticObject.getActivity());
		feeder.accept(grammarAccess.getTabAccess().getImageTabImageIDTerminalRuleCall_6_0_1(), semanticObject.getImage());
		feeder.finish();
	}
}
